package manager

import (
	"github.com/Codehardt/go-cpulimit"
	"github.com/shirou/gopsutil/cpu"
	"sync/atomic"
	"time"
)

var (
	cpuLoadStatus  = atomic.Int32{}
	usageThreshold = float64(60)
	limiter        *cpulimit.Limiter
)

const (
	cpuLoadNoData = iota
	cpuLoadUpward
	cpuLoadDownward
)

func init() {

	limiter = &cpulimit.Limiter{
		MaxCPUUsage:     50.0,                   // throttle if current cpu usage is over 50%
		MeasureInterval: time.Millisecond * 333, // measure cpu usage in an interval of 333 milliseconds
		Measurements:    3,                      // use the average of the last 3 measurements for cpu usage calculation
	}

	_ = limiter.Start()

	go func() {
		for {
			cpuMonitorBackGround()
		}
	}()
}

func Run(f func()) {

	f()
	return
	limiter.Wait()
	for cpuLoadStatus.Load() == cpuLoadUpward {
		time.Sleep(time.Millisecond * 5)
	}
	f()
	return
}

/*
监控 cpu 负载情况
*/
func cpuMonitorBackGround() {
	// 定义采样的时间间隔和持续时间
	sampleInterval := 500 * time.Millisecond // 采样间隔
	totalDuration := 7 * time.Second         // 总采样时间

	// 计算总采样次数
	totalSamples := int(totalDuration / sampleInterval)

	// 初始化存储 CPU 使用率历史数据的切片
	cpuUsageHistory := make([]float64, 0, totalSamples)

	for i := 0; i < totalSamples; i++ {
		cpuUsage, err := cpu.Percent(sampleInterval, false)
		if err != nil {
			time.Sleep(sampleInterval)
			continue
		}

		// 获取所有 CPU 核心的平均使用率
		averageCPUUsage := calculateAverage(cpuUsage)

		//log.Info(fmt.Sprintf("获取所有 CPU 核心的平均使用率:%v 历史数据切片:%+v", averageCPUUsage, cpuUsageHistory))
		// 将使用率添加到历史数据中
		cpuUsageHistory = append(cpuUsageHistory, averageCPUUsage)

		time.Sleep(sampleInterval)
	}

	trend := int32(calculateTrend(cpuUsageHistory))
	//log.Info(fmt.Sprintf("历史数据切片:%+v,计算的cpu变化趋势:%v", cpuUsageHistory, trend))

	// 计算 CPU 使用率的变化趋势
	cpuLoadStatus.Store(int32(trend))
}

func calculateAverage(values []float64) float64 {
	sum := 0.0
	for _, value := range values {
		sum += value
	}
	return sum / float64(len(values))
}

func calculateTrend(data []float64) int {

	if len(data) <= 1 {
		return cpuLoadNoData
	}

	// 统计上升和下降的样本数量
	upwardCount := 0
	downwardCount := 0

	// 比较两两样本数据
	for i := 1; i < len(data); i++ {
		if data[i] > data[i-1] || (data[i] >= usageThreshold && data[i-1] >= usageThreshold) {
			upwardCount++
		} else if data[i] < data[i-1] {
			downwardCount++
		}
	}

	// 如果半数以上的上升数据出现在后半部分，则返回 "CPU 使用率上升"
	if upwardCount > downwardCount && upwardCount >= (len(data)-len(data)/2) {
		return cpuLoadUpward
	}

	return cpuLoadDownward
}
